﻿#include <QCoreApplication>
#include <stdio.h>
#include <string.h>

#define ARRAY_SIZE(array)   (sizeof(array)/sizeof(array[0]))

#define MULTI -2
#define NONE  -1

#define MAX_LAYER 10


char meterNum1[][MAX_LAYER+1]=
{
    "888AAAAAAA",
    "1234567890",
    "8882234550",
    "8881234550",
    "8881334550",
    "8881234560",
    "1881234561",
    "1881234562",
    "8881234563",
    "8881234564",
    "8881234565",
    "8881234566",
    "8881234567",
    "8881234568",
    "8881234569",
    "8881234559",
    "8881234549",
    "8881234449",
    "8881234349",
    "8881254349",
};

char meterNum2[][MAX_LAYER]=
{
    "AAAAAAA",
    "8880000",
    "8889999",
    "8881234",
    "8884683",
    "8888565",
    "8884578",
    "8881358",
    "8887855",
    "8882352",
    "8882467",
    "8888568",
    "8881345",
    "8881235",
    "8882464",
};

char meterNum[][MAX_LAYER+1]=
{
    "888AAAAAAA",
    "1234567992",
    "1234568992",

};

/*
形参：@addr 地址字符串
     @match 要匹配的字符串，'A'为通配符
返回：匹配返回0，否则返回-1

*/
int8_t compare_meter_addr(const char addr[], const char match[])
{
    int i;
    //printf("addr_num=%s\n", addr);
    //printf("match=%s\n", match);

    for(i = MAX_LAYER - 1; i > 0 ; i--)
    {
        //printf("match[%d]=%c\n", i, match[i]) ;
        if(match[i] == 'A')
        {
            //printf("continue\n") ;
            continue;
        }

        //printf("!=A\n") ;
        if(addr[i] != match[i])
            return -1;
    }
    return 0;

}



/*
形参：条件通配符
返回值：
没有符合条件的，返回-1
有唯一符合条件的，返回它在数组中的序号
有多个符合条件的，返回-2
*/
int8_t device_handle(char *match)
{
    unsigned int i;
    int match_cnt = 0;//匹配成功的次数
    int match_idx;



    for(i = 1; i < ARRAY_SIZE(meterNum); i++)
    {
        int8_t ret = compare_meter_addr(meterNum[i], match);
        if(0 == ret)
        {
            match_cnt++;
            match_idx = i;
        }

    }

    switch(match_cnt)
    {
        case 0: return NONE;
        case 1: return match_idx;
        default:return MULTI;
    }
    return 0;
}

//统计字符串前面有几个连续A,
//返回值一定介于[0,7]
uint8_t cnt_A_in_Str(char *str)
{
    uint8_t cntA = 0;
    int i=0;
    for(i = 0; i < MAX_LAYER; i++)
    {
        if(str[i] == 'A')
            cntA++;
        else
            break;

    }
    return cntA;
}


static int find_cnt = 0;//找到的次数
static int search_cnt=0;//搜索的次数
int8_t f(char *match)
{
    uint8_t cntA = cnt_A_in_Str(match);

    //printf("match = %s\n", match);

    int8_t response = device_handle(match);//例如，本应4个冲突，一个也上不来，结果因为运气好，结果随机延时上来了2个，另外两个冲突掉了，这种情况没有搜全，故仍需按冲突处理

    search_cnt++;
    printf("[%3d] ", search_cnt);
    if((response > 0) || (response == NONE) )//单响应或无响应
    {
        if((response > 0))//单响应
        {
            printf("%s match single", match);
            find_cnt++;
            printf("find = %s,------------------------%d\n", meterNum[response], find_cnt);
        }
        else//无响应
        {
            printf("%s match NONE", match);
        }


        if(match[cntA] <= '8')//本级尚未完成
        {
            printf("->same class->go forward\n");
            match[cntA] = match[cntA] + 1;//同级前进
        }
        else//match[cntA]==9，同级节点已搜索完毕，
        {
            if(cntA == (MAX_LAYER - 1))//本级节点为：顶级节点
            {
                printf("->digit 0 scaned '9'->end\n");
                return -3;//终止条件
            }
            else//本级节点为：非顶级节点
            {
                printf("->digit 1-6 scaned '9'->go up to parent\n");
                printf("match[cntA]=%C, match[cntA=1]=%C\n",match[cntA],match[cntA+1] );
                match[cntA] = 'A';
                if(match[cntA + 1] >= '9')
                {
                    //match[cntA + 1] = 'A';//回上层
                }
                else
                    match[cntA + 1] += 1;//回上层
            }
        }
        return f(match);
    }    
    else if(response == MULTI)
    {
        printf("%s match multi", match);
        if(cntA >= 1)//本级节点为：非最底级节点
        {
            printf("->go down to child's '0'\n");
            match[cntA - 1] = '0';//进入下一层的第0个
            return f(match);
        }
        else//本级节点为：最低级节点。这个else不可能进入：因为最低级节点一定是单响应的，永远不可能发生多响应，除非有两个设备地址相同
        {
            printf("error: at lease 2 devices have same addr!\n");
            return NONE;
        }
    }

    return 0;//该return无意义，不可能运行到这里，为了避免编译警告
}





int main(void)
{
    //int ret;

    //printf("%s\n", str);

    char *match = meterNum[0];
    printf("device cnt = %d\n", ARRAY_SIZE(meterNum) -1);
    memset(match, 'A', MAX_LAYER - 1);
    match[MAX_LAYER - 1] = '0';
//    ret = f(match);
//    printf("end->%d\n", ret);
//    return 0;

    int cur_layer = 0;
    char cur_node_each_layer[MAX_LAYER];
    memset(cur_node_each_layer, '0', MAX_LAYER);

    while(1)
    {
        int layer;
        memset(match, 'A', MAX_LAYER);
        for(layer = 0; layer <= cur_layer; layer++)
        {
            match[MAX_LAYER - 1 - layer] = cur_node_each_layer[layer];
        }

        int8_t response = device_handle(match);
        search_cnt++;
        printf("[%3d] ", search_cnt);
        if((response > 0) || (response == NONE) )//单响应或无响应
        {
            if((response > 0))//单响应
            {
                printf("%s match single", match);
                find_cnt++;
                printf("find = %s,------------------------%d\n", meterNum[response], find_cnt);
            }
            else//无响应
            {
                printf("%s match NONE", match);
            }

            if(cur_node_each_layer[cur_layer] <= '8')//本级尚未完成
            {
                printf("->same class->go forward\n");
                cur_node_each_layer[cur_layer] += 1;//同级前进
            }
            else//本级10个节点已搜索完毕，回上n层
            {            
                printf("->digit 1-6 scaned '9'->go up to parent\n");

                while(1)//回到上一个不是9的层
                {
                    cur_layer--;//向上回一层
                    if(cur_layer < 0) cur_layer = 0;

                    if(cur_node_each_layer[cur_layer] < '9')
                    {
                        cur_node_each_layer[cur_layer]++;
                        break;
                    }
                    else
                    {
                        if(cur_layer <= 0) //顶层全都是9 =>回到了顶级节点
                            break;
                        else
                            cur_node_each_layer[cur_layer] = 'A';
                    }
                }
                if((cur_layer <= 0) && (cur_node_each_layer[cur_layer] == '9')) //回到了顶级节点
                    break;

            }
        }
        else if(response == MULTI)
        {
            printf("%s match multi", match);
            if(cur_layer == (MAX_LAYER - 1))//本级节点为：最低级节点。这个else不可能进入：因为最低级节点一定是单响应的，永远不可能发生多响应，除非有两个设备地址相同
            {
                printf("error: at lease 2 devices have same addr!\n");
                break;
            }
            else//本级节点为：非最底级节点
            {
                printf("->go down to child's '0'\n");
                cur_layer++;
                cur_node_each_layer[cur_layer] = '0';//进入下一层的第0个
            }
        }
    }

//    while(1)
//    {
//        uint8_t cntA = cnt_A_in_Str(match);
//        int8_t response = device_handle(match);
//        search_cnt++;
//        printf("[%3d] ", search_cnt);
//        if((response > 0) || (response == NONE) )//单响应或无响应
//        {
//            if((response > 0))//单响应
//            {
//                printf("%s match single", match);
//                find_cnt++;
//                printf("find = %s,------------------------%d\n", meterNum[response], find_cnt);
//            }
//            else//无响应
//            {
//                printf("%s match NONE", match);
//            }

//            if(match[cntA] <= '8')//本级尚未完成
//            {
//                printf("->same class->go forward\n");
//                match[cntA] += 1;//同级前进
//            }
//            else//match[cntA]==9，同级节点已搜索完毕，
//            {
//                if(cntA == (MAX_LAYER - 1))//本级节点为：顶级节点
//                {
//                    printf("->digit 0 scaned '9'->end\n");
//                    break;//终止条件
//                }
//                else//本级节点为：非顶级节点
//                {
//                    printf("->digit 1-6 scaned '9'->go up to parent\n");
//                    match[cntA] = 'A';
//                    match[cntA + 1] += 1;//回上层
//                    //cur_layer_idx--;
//                }
//            }
//        }
//        else if(response == MULTI)
//        {
//            printf("%s match multi", match);
//            if(cntA >= 1)//本级节点为：非最底级节点
//            {
//                printf("->go down to child's '0'\n");
//                match[cntA - 1] = '0';//进入下一层的第0个
//                //cur_layer_idx++;
//            }
//            else//本级节点为：最低级节点。这个else不可能进入：因为最低级节点一定是单响应的，永远不可能发生多响应，除非有两个设备地址相同
//            {
//                printf("error: at lease 2 devices have same addr!\n");
//                break;
//            }
//        }
//    }
    //printf("end->%d\n", ret);


    return 0;
}
